module Engine
  protected

	def graph_today
		stocks = Stock.open_stocks
		for stock in stocks
			graph = Scruffy::Graph.new
			graph.title = "Today's Movement"
			graph.renderer = Scruffy::Renderers::Standard.new
			history = History.top(stock.id)
			if !history.close.nil?
				graph.add :line, stock.name, [history.open, history.high, history.low, history.close]
				graph.point_markers = ['Open', 'High', 'Low', 'Close']
			else
				graph.add :line, stock.name, [history.open, history.high, history.low, stock.market_value]
				graph.point_markers = ['Open', 'High', 'Low', 'Now']
			end
			graph.render :to => "public/images/"+stock.name+"_today.svg"
			graph.render  :width => 300, :height => 200,
			  :to => "public/images/"+stock.name+"_today.png", :as => 'png'
		end
	end

	def graph
		stocks = Stock.open_stocks
		for stock in stocks
			graph1 = graph2 = Scruffy::Graph.new
			graph1.title = "Long Term Price Movement"
			graph2.title = "Day wise Volumes (no. of shares)"
			graph1.renderer = graph2.renderer = Scruffy::Renderers::Standard.new



			#graph.renderer = Scruffy::Renderers::Standard.new
			histories = History.find(	:all,
										:conditions => "stock_id = '#{stock.id}'")
			price = volume = Array.new
			for history in histories
				if !history.close.nil?
					price << history.close
				else
					price << stock.market_value
				end
				volume << history.volume
			end
			graph1.add :line, stock.name, price, :category => :top
			graph2.add :bar,  'Volume Traded', volume, :category => :bottom
			graph1.point_markers = graph1.point_markers = (0..Flag.day).to_a
			graph1.render :to => "public/images/"+stock.name+".svg"
			graph2.render :to => "public/images/"+stock.name+"_volumes.svg"
			graph1.render  :width => 500, :height => 200,
			  :to => "public/images/"+stock.name+".png", :as => 'png'
						graph1.render :to => "public/images/"+stock.name+".svg"
			graph2.render  :width => 500, :height => 200,
			  :to => "public/images/"+stock.name+"_volumes.png", :as => 'png'
		end	
	end
		
	def update_freemex
		stocks = Stock.open_stocks
		#freemex = 0
		old_market_cap = new_market_cap = 0
		#market_cap = Hash.new
		for stock in stocks
			old_price = History.first(:conditions => "stock_id = '#{stock.id}'").open
			old_market_cap += old_price * stock.quantity
			#market_cap[stock.id] = stock.market_value * stock.quantity
			new_market_cap += stock.market_value * stock.quantity
		end
		freemex = (new_market_cap/old_market_cap)*1000
		stock = Stock.find(1)
		stock.market_value = freemex
		stock.save!
		return freemex
	end
	
    def add_update(user_id, stock_id, quantity, what, price)
		update = Update.new(:user_id => user_id, :stock_id => stock_id, :quantity => quantity, :what => what, :price => price)
		update.save!
	end

	def delete_trigger(id)
		trigger = Trigger.find(id)		
		trigger.destroy
	end

	def update_trigger(id, quantity)
		trigger = Trigger.find(id)
		trigger.quantity -= quantity
		trigger.save
	end

	def update_ownership(user_id, stock_id, what, price, quantity)
		shrink = Ownership.instance(user_id, stock_id)
		if what == "+"
			if shrink.nil?
				shrink = Ownership.new
				shrink.user_id = user_id
				shrink.stock_id = stock_id
				shrink.bought_at = price
				shrink.quantity = quantity
			else
				shrink.bought_at = (shrink.bought_at*shrink.quantity + price*quantity)/(shrink.quantity + quantity)
				shrink.quantity += quantity
			end
			shrink.save	
		else
			if shrink.quantity == quantity
				ownership = Ownership.find(shrink.id)		
				ownership.destroy
			else
				shrink.bought_at = (shrink.bought_at*shrink.quantity - price*quantity)/(shrink.quantity - quantity)
				shrink.quantity -= quantity
				shrink.save
			end
		end	
	end
	
	def change_cash(id, what, money)
		user = User.find(id)
		if what == "+"
			user.cash += money
		else
			user.cash -= money	
		end
		user.save!
	end
	
	def brokerage(money)
		return money*1/100
	end
	
	def transfer(buys, sells)
		stock = Stock.find(buys.stock_id)
		buyer = User.find(buys.user_id)
		seller = User.find(sells.user_id)
		if buys.price*buys.quantity+brokerage(buys.price*buys.quantity) > buyer.cash
			delete_trigger(buys.id)
			add_update(buys.user_id, buys.stock_id, buys.quantity, "defunct", buys.price)	
			return
		end		
		if Ownership.owns(seller.id, sells.stock_id) < sells.quantity
			delete_trigger(sells.id)
			add_update(sells.user_id, sells.stock_id, sells.quantity, "defunct", sells.price)	
			return
		end		
		if buys.quantity <= sells.quantity
			delete_trigger(buys.id)
			if buys.quantity == sells.quantity
				delete_trigger(sells.id)
			else
				update_trigger(sells.id, buys.quantity)
			end
			update_ownership(buys.user_id, buys.stock_id, "+", buys.price, buys.quantity)
			update_ownership(sells.user_id, sells.stock_id, "-", buys.price, buys.quantity)
			quantity_traded = buys.quantity
		else
			delete_trigger(sells.id)
			update_trigger(buys.id, sells.quantity)
			update_ownership(buys.user_id, buys.stock_id, "+", buys.price, sells.quantity)
			update_ownership(sells.user_id, sells.stock_id, "-", buys.price, sells.quantity)
			quantity_traded = sells.quantity
		end
		change_cash(buys.user_id, "-", (quantity_traded*buys.price)+brokerage(quantity_traded*buys.price))
		add_update(buys.user_id, buys.stock_id, quantity_traded, "bought", buys.price)
		change_cash(sells.user_id, "+", (quantity_traded*buys.price)-brokerage(quantity_traded*buys.price))
		add_update(sells.user_id, buys.stock_id, quantity_traded, "sold", buys.price)
		
		stock.market_value = sells.price
		stock.save!
		history = History.top(stock.id)
		if stock.market_value > history.high
			history.high = stock.market_value
		elsif stock.market_value < history.low
			history.low = stock.market_value
		end
		history.volume += quantity_traded
		history.save!
		#graph_today
		#return quantity_traded
	end

	def engine
		stocks = Stock.find(:all)
		for stock in stocks
			triggers_buy = Trigger.filter(stock.id, "buy")
			triggers_sell = Trigger.filter(stock.id, "sell")
			for buys in triggers_buy
				for sells in triggers_sell
					if buys.user_id != sells.user_id
						if sells.price <= buys.price
							transfer(buys,sells)
						else
							break
						end
					end
				end
			end
		end	
	end
	
	def engine2(trigger)
		if trigger.action == "buy"
			pop = Trigger.pop(trigger.stock_id, "sell")
			if trigger.user_id != pop.user_id && pop.price <= trigger.price
				transfer(trigger,pop)
			end
		else
			pop = Trigger.filter(trigger.stock_id, "buy")
			if trigger.user_id != pop.user_id && trigger.price <= pop.price
				transfer(pop,trigger)
			end
		end
	end
	
end
